home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / comm / tcp / amitcpfinger.lha / finger / finger.c < prev    next >
C/C++ Source or Header  |  1993-08-10  |  7KB  |  269 lines

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. char copyright[] =
  39. "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
  40.  All rights reserved.\n";
  41. #endif /* not lint */
  42.  
  43. #ifndef lint
  44. static char sccsid[] = "@(#)finger.c    5.22 (Berkeley) 6/29/90";
  45. #endif /* not lint */
  46.  
  47. /*
  48.  * Finger prints out information about users.  It is not portable since
  49.  * certain fields (e.g. the full user name, office, and phone numbers) are
  50.  * extracted from the gecos field of the passwd file which other UNIXes
  51.  * may not have or may use for other things.
  52.  *
  53.  * There are currently two output formats; the short format is one line
  54.  * per user and displays login name, tty, login time, real name, idle time,
  55.  * and office location/phone number.  The long format gives the same
  56.  * information (in a more legible format) as well as home directory, shell,
  57.  * mail info, and .plan/.project files.
  58.  */
  59.  
  60. #include <sys/param.h>
  61. #include <sys/file.h>
  62. #include <stdio.h>
  63. #include "finger.h"
  64.  
  65. time_t now;
  66. int lflag, sflag, pplan;
  67. #ifndef __GNUC__
  68. int mflag;
  69. #endif
  70. char tbuf[1024];
  71.  
  72. #ifdef __GNUC__
  73. extern void _STDcloseSockets(void);
  74. char *_ProgramName;
  75. #endif
  76.  
  77. main(argc, argv)
  78.     int argc;
  79.     char **argv;
  80. {
  81.     extern int optind;
  82.     int ch;
  83.     time_t time();
  84.  
  85. #ifdef __GNUC__
  86.     _ProgramName=argv[0];
  87.     atexit(_STDcloseSockets);
  88.     _STIopenSockets();
  89.     while ((ch = getopt(argc, argv, "lps")) != EOF)
  90. #else
  91.     while ((ch = getopt(argc, argv, "lmps")) != EOF)
  92. #endif
  93.         switch(ch) {
  94.         case 'l':
  95.             lflag = 1;        /* long format */
  96.             break;
  97. #ifndef __GNUC__
  98.         case 'm':
  99.             mflag = 1;        /* force exact match of names */
  100.             break;
  101. #endif
  102.         case 'p':
  103.             pplan = 1;        /* don't show .plan/.project */
  104.             break;
  105.         case 's':
  106.             sflag = 1;        /* short format */
  107.             break;
  108.         case '?':
  109.         default:
  110.             (void)fprintf(stderr,
  111.                 "usage: finger [-lmps] [login ...]\n");
  112.             exit(1);
  113.         }
  114.     argc -= optind;
  115.     argv += optind;
  116.  
  117.     (void)time(&now);
  118. #ifndef __GNUC__
  119.     setpassent(1);
  120. #endif
  121.     if (!*argv) {
  122.         /*
  123.          * Assign explicit "small" format if no names given and -l
  124.          * not selected.  Force the -s BEFORE we get names so proper
  125.          * screening will be done.
  126.          */
  127.         if (!lflag)
  128.             sflag = 1;    /* if -l not explicit, force -s */
  129.         loginlist();
  130.         if (entries == 0)
  131.             (void)printf("No one logged on.\n");
  132.     } else {
  133.         userlist(argc, argv);
  134.         /*
  135.          * Assign explicit "large" format if names given and -s not
  136.          * explicitly stated.  Force the -l AFTER we get names so any
  137.          * remote finger attempts specified won't be mishandled.
  138.          */
  139.         if (!sflag)
  140.             lflag = 1;    /* if -s not explicit, force -l */
  141.     }
  142.     if (entries != 0) {
  143.         if (lflag)
  144.             lflag_print();
  145.         else
  146.             sflag_print();
  147.     }
  148.     exit(0);
  149. }
  150.  
  151. loginlist()
  152. {
  153.     register PERSON *pn;
  154. #ifndef __GNUC__
  155.     struct passwd *pw;
  156.     struct utmp user;
  157.     char name[UT_NAMESIZE + 1];
  158.     if (!freopen(_PATH_UTMP, "r", stdin)) {
  159.         (void)fprintf(stderr, "finger: can't read %s.\n", _PATH_UTMP);
  160.         exit(2);
  161.     }
  162.     name[UT_NAMESIZE] = NULL;
  163.     while (fread((char *)&user, sizeof(user), 1, stdin) == 1) {
  164.         if (!user.ut_name[0])
  165.             continue;
  166.         if ((pn = find_person(user.ut_name)) == NULL) {
  167.             bcopy(user.ut_name, name, UT_NAMESIZE);
  168.             if ((pw = getpwnam(name)) == NULL)
  169.                 continue;
  170.             pn = enter_person(pw);
  171.         }
  172.         enter_where(&user, pn);
  173.     }
  174. #endif
  175.     for (pn = phead; lflag && pn != NULL; pn = pn->next)
  176.         enter_lastlog(pn);
  177. }
  178.  
  179. userlist(argc, argv)
  180.     register argc;
  181.     register char **argv;
  182. {
  183.     register i;
  184.     register PERSON *pn;
  185.     PERSON *nethead, **nettail;
  186.     struct utmp user;
  187.     struct passwd *pw;
  188.     int dolocal, *used;
  189.     char *index();
  190.  
  191.     if (!(used = (int *)calloc((u_int)argc, (u_int)sizeof(int)))) {
  192.         (void)fprintf(stderr, "finger: out of space.\n");
  193.         exit(1);
  194.     }
  195.  
  196.     /* pull out all network requests */
  197.     for (i = 0, dolocal = 0, nettail = &nethead; i < argc; i++) {
  198.         if (!index(argv[i], '@')) {
  199.             dolocal = 1;
  200.             continue;
  201.         }
  202.         pn = palloc();
  203.         *nettail = pn;
  204.         nettail = &pn->next;
  205.         pn->name = argv[i];
  206.         used[i] = -1;
  207.     }
  208.     *nettail = NULL;
  209.  
  210. #ifndef __GNUC__
  211.     if (!dolocal)
  212.         goto net;
  213.  
  214.     /*
  215.      * traverse the list of possible login names and check the login name
  216.      * and real name against the name specified by the user.
  217.      */
  218.     if (mflag) {
  219.         for (i = 0; i < argc; i++)
  220.             if (used[i] >= 0 && (pw = getpwnam(argv[i]))) {
  221.                 enter_person(pw);
  222.                 used[i] = 1;
  223.             }
  224.     } else while (pw = getpwent())
  225.         for (i = 0; i < argc; i++)
  226.             if (used[i] >= 0 &&
  227.                 (!strcasecmp(pw->pw_name, argv[i]) ||
  228.                 match(pw, argv[i]))) {
  229.                 enter_person(pw);
  230.                 used[i] = 1;
  231.             }
  232.     /* list errors */
  233.     for (i = 0; i < argc; i++)
  234.         if (!used[i])
  235.             (void)fprintf(stderr,
  236.                 "finger: %s: no such user.\n", argv[i]);
  237.  
  238.     /* handle network requests */
  239. #endif
  240. net:    for (pn = nethead; pn; pn = pn->next) {
  241.         netfinger(pn->name);
  242.         if (pn->next || entries)
  243.             putchar('\n');
  244.     }
  245.  
  246.     if (entries == 0)
  247.         return;
  248.  
  249.     /*
  250.      * Scan thru the list of users currently logged in, saving
  251.      * appropriate data whenever a match occurs.
  252.      */
  253. #ifndef __GNUC__
  254.     if (!freopen(_PATH_UTMP, "r", stdin)) {
  255.         (void)fprintf( stderr, "finger: can't read %s.\n", _PATH_UTMP);
  256.         exit(1);
  257.     }
  258.     while (fread((char *)&user, sizeof(user), 1, stdin) == 1) {
  259.         if (!user.ut_name[0])
  260.             continue;
  261.         if ((pn = find_person(user.ut_name)) == NULL)
  262.             continue;
  263.         enter_where(&user, pn);
  264.     }
  265. #endif
  266.     for (pn = phead; pn != NULL; pn = pn->next)
  267.         enter_lastlog(pn);
  268. }
  269.